from django.core.paginator import Paginator, InvalidPage
from django.db.models import Q
from django.forms import model_to_dict
from django.http import JsonResponse, QueryDict
from django.utils.decorators import method_decorator
from django.views import View

from tools import beautify_dict, format_date, format_datetime, get_int
from .models import Resume
from tools.response_code import get_resp_dict
from tools.token import check_token, get_user


class ResumesView(View):
    """
    ResumesView视图：处理resume_resume表的各种操作
    访问路由：/resume/resumes
    """

    @method_decorator(check_token)
    def post(self, request):
        """
        创建新简历
        """
        req_dict = beautify_dict(
            request.POST.dict(),
            {'public': int, 'sex': int},
            lambda x: (None if x == '' else x)
        )
        # print(req_dict)
        req_dict['user'] = request.user
        try:
            Resume.objects.create(**req_dict)
        except Exception as e:
            print(e)
            return JsonResponse(get_resp_dict(code=99999))

        return JsonResponse(get_resp_dict())

    def get(self, request):
        """
        获取满足条件的简历列表，需要做分页
        """
        uid = get_int(request.GET.get('uid'))  # 该用户id表明访问者想要访问哪个用户的简历
        cur_page = get_int(request.GET.get('page'), 1)  # 简历列表的第几页
        visitor = get_user(request)  # 访问者的用户信息
        if uid:  # 指定访问该用户的简历
            if visitor:  # 访问者已登录
                if visitor.id == uid:  # 访问者访问自己的简历
                    resumes = Resume.objects.filter(user_id=uid)
                else:  # 访问者访问别人的简历
                    resumes = Resume.objects.filter(user_id=uid, public=True)
            else:  # 访问者是游客
                resumes = Resume.objects.filter(user_id=uid, public=True)
        else:  # 访问所有用户的简历
            if visitor:  # 访问者已登录
                resumes = Resume.objects.filter(Q(public=True) | Q(user_id=visitor.id))
            else:  # 访问者是游客
                resumes = Resume.objects.filter(public=True)

        try:
            paginator = Paginator(resumes, 10)
            page = paginator.page(cur_page)
            page_list = [beautify_resume(m) for m in page]
            result = {
                'page_list': page_list,
                'count': paginator.count,
                'num_pages': paginator.num_pages,
                'page_number': page.number,
                'per_page': paginator.per_page,
            }
        except InvalidPage as e:
            print(e)
            return JsonResponse(get_resp_dict(code=404))
        except Exception as e:
            print(e)
            return JsonResponse(get_resp_dict(code=99999))

        return JsonResponse(get_resp_dict(result))


class ResumeView(View):
    """
    ResumeView视图：针对resume_resume表中的某条记录进行操作
    访问路由：/resume/resumes/<int:id>
    """

    def get(self, request, id):
        """
        获取指定id的简历信息
        """
        try:
            resume = Resume.objects.get(id=id)
        except Exception as e:
            print(e)
            return JsonResponse(get_resp_dict(code=404))

        if resume.public:  # 公开的简历
            resume_dict = beautify_resume(resume)
            return JsonResponse(get_resp_dict(resume_dict))
        else:  # 私有简历，只有作者可看
            visitor = get_user(request)  # 访问者的用户信息
            if visitor:  # 访问者已登录
                if visitor.id == resume.user_id:
                    resume_dict = beautify_resume(resume)
                    return JsonResponse(get_resp_dict(resume_dict))
                else:
                    return JsonResponse(get_resp_dict(code=401))
            else:  # 访问者是游客
                return JsonResponse(get_resp_dict(code=401))

    @method_decorator(check_token)
    def delete(self, request, id):
        """
        删除指定id的简历信息
        只有简历主人才可以删除
        """
        try:
            resume = Resume.objects.get(id=id, user=request.user)
            resume.delete()
        except Exception as e:
            print(e)
            return JsonResponse(get_resp_dict(code=99999, msg='删除失败'))

        return JsonResponse(get_resp_dict('删除成功'))

    @method_decorator(check_token)
    def put(self, request, id):
        """
        更新指定id的简历信息
        只有简历主人才可以修改
        """
        try:
            resumes = Resume.objects.filter(id=id, user=request.user)
        except Exception as e:
            print(e)
            return JsonResponse(get_resp_dict(code=99999))

        req_dict = beautify_dict(
            QueryDict(request.body).dict(),
            {'public': int, 'sex': int},
            lambda x: (None if x == '' else x)
        )

        try:
            resumes.update(**req_dict)
            resume_dict = beautify_resume(resumes[0])
            return JsonResponse(get_resp_dict(resume_dict))
        except Exception as e:
            print(e)
            return JsonResponse(get_resp_dict(code=99999))


def beautify_resume(resume):
    """
    将resume Model对象美化为一个字典
    :param resume: 一条简历记录的Model对象
    :return: 返回一个字典
    """
    resume_dict = beautify_dict(
        model_to_dict(resume),
        {
            'birth': format_date,
            'begin_work': format_date,
        },
    )

    # DateTime 字段有auto_now_add = True和auto_now = True属性的
    # 会默认添加editable = False隐藏属性
    # 因此 resume_dict 里面没有 created_time 和 updated_time
    resume_dict['created_time'] = format_datetime(resume.created_time)
    resume_dict['updated_time'] = format_datetime(resume.updated_time)
    return resume_dict
